public class DeterministicFiniteAutomata extends FiniteAutomata
{
	/*
	 * MEMBER VARIABLES
	 */
	
	private State _activeState;
	
	
	
	/*
	 * CONSTRUCTORS
	 */
	
	public DeterministicFiniteAutomata()
	{
		super();
	}
	
	public DeterministicFiniteAutomata(String input)
	{
		super(input);
	}
	
	
	
	/*
	 * CONCRETE METHODS
	 */
	
	// Remember to verify this is a VALID and COMPLETE DFA before calling! 
	// NO checks are performed here, they MUST be done beforehand
	// Call isValid() first!  
	@Override
	public boolean simulate(String[] word) // Note:  word[0] will be null, ignore
	{
		this._activeState = this._states[0];
		for (int i = 1; i < word.length; i++)
		{
			if (this._activeState == null)
			{
				return false;
			}
			this._activeState = this.getStateFromName(this._activeState.DFAtrans(word[i]));
		}
		if (this._activeState.getAccepting())
		{
			return true;
		}
		return false;
	}

	// Checks if the DFA is valid and complete.  
	// Note that this won't always be the case.  
	// Partially completed DFAs can be saved.  
	@Override
	public String isValid()
	{
		// First make sure there's a starting state.  
		if (this._states[0] == null)
		{
			return "No starting state.";
		}
		// Note that it's okay to not have any accepting states.  Just dumb. 
		String[] names = new String[this._stateCount - 1];
		int m = 0;
		for (int i = 1; i <= this._stateCount; i++)
		{
			// Then make sure no two states share the same name.  
			for (int j = 0; j < m; j++)
			{
				if (this._states[i].getName().equals(names[j]))
				{
					return "There are two states with the name " + this._states[i].getName() + ".";
				}
			}
			names[m] = this._states[i].getName();
			// Then make sure no state has two transitions for the same letter.
			for (String letter : this._alphabet)
			{
				if (this._states[i].NFAtrans(letter, this._stateCount).length > 1)
				{ // NFAtrans returns all states letter maps to in an array.
					return this._states[i].getName() + " has two transitions for the letter \"" + letter + "\".";
				}
			}
			// Finally, make sure no states have transitions for letters
			// that aren't in the alphabet.  
			String[] transitions = this._states[i].getTransitions();
			int transitionCount = this._states[i].getTransitionCount();
			for (int j = 0; j < transitionCount; j++)
			{
				if (!this.containsLetter(transitions[2 * j]))
				{
					return this._states[i].getName() + " has a transition for the letter " + transitions[2 * j] + ", which is not in the alphabet.";
				}
			}
		}
		// Note that the last three checks would each need their own
		// identical loop from i = 1 to this._stateCount if they didn't
		// share the one they're in.  
		return "VALID";
	}
	
}